/*************************************************************************
	Button,ToggleButton, RadioButton, ChechBox,TabItem, etc

*************************************************************************/

using UnityEngine;
using System;
using System.Collections;

[Serializable]
public class UKagButton_SaveData : UKagControlBase_SaveData
{
	public UKagButton_SaveData() {}
		
	public UKagButton.BUTTON_TYPE type = UKagButton.BUTTON_TYPE.NORMAL;
		
	public bool selected = false;
	
	public string targetScenario = null;
	public string targetLabel = null;
	
	public string eventTarget = null;
	public string eventParam = null;
}

[RequireComponent(typeof(UTVPAnimationLayer))]
public class UKagButton : UKagControlBase {

	public delegate void OnButtonEventDelegate(UKagButton btn);

	public enum BUTTON_TYPE
	{
		NORMAL,
		AUTOREPEAT,
		RADIO,
		CHECK
	}
	
	public enum CONTROL_STATE
	{
		NORMAL,
		OVER,
		ON,
		DISABLE,
		SELECTEDNORMAL, // for RadioButton and ChechBox
		SELECTEDOVER, // for RadioButton and ChechBox
		SELECTEDON, // for RadioButton and ChechBox
		SELECTEDDISABLE, // for RadioButton and ChechBox
		
		SIZE
	}
	
	public static string[] stateSuffix = { "Normal", "Over", "On", "Disable", "SelectedNormal", "SelectedOver", "SelectedOn", "SelectedDisable" };
	
	public BUTTON_TYPE type = BUTTON_TYPE.NORMAL;
	public string RadioButtonGroup = null;

	private bool _selected = false;
	
	public OnButtonEventDelegate OnButtonClick = null;
	public OnButtonEventDelegate OnButtonEnter = null;
	public OnButtonEventDelegate OnButtonLeave = null;
	public OnButtonEventDelegate OnButtonSelected = null;
	
	public string targetScenario = null;
	public string targetLabel = null;
	
	public GameObject eventTarget = null;
	public string eventParam = null;
	
	// Use this for initialization
	protected override void Awake () {
		base.Awake();

		if (eventParam == null)
			eventParam = this.name;
	}
	
	public bool selected
	{
		get { return _selected; }
		set
		{
			if (_selected == value)
				return;
			
			_selected = value;
			
			RefreshControlState();
			if (_selected && type == BUTTON_TYPE.RADIO)
				parent.RefreshRadioButtonState(this);
			if (OnButtonSelected != null)
				OnButtonSelected(this);
		}
	}
	
	public void SetButtonOpt(string animPrefix, bool isAnim)
	{
		SetButtonOpt(mIsSys, null, type, animPrefix, isAnim);
	}
	
	public void SetButtonOpt(bool isSys, UTVPImage img, BUTTON_TYPE type, string animPrefix, bool isAnim)
	{
		SetButtonOpt(isSys, img, type, animPrefix, isAnim, mTargetLayer.Left, mTargetLayer.Top);
	}
	public void SetButtonOpt(bool isSys, UTVPImage img, BUTTON_TYPE type, string animPrefix, bool isAnim, int x, int y)
	{
		SetButtonOpt(isSys, img, type, animPrefix, isAnim, x, y, 0, 0);
	}
	public void SetButtonOpt(bool isSys, UTVPImage img, BUTTON_TYPE type, string animPrefix, bool isAnim, int x, int y, int width, int height)
	{
		mIsSys = isSys;
		this.type = type;
		if (img != null)
			mTargetLayer.LoadImage(img);
		else
			img = mTargetLayer.Image;
		stateAnimNamePrefix = animPrefix;
		mIsAnim = isAnim;
		
		UTVPAnimFrameInfo normalFrame = null;
		if (mIsAnim)
			normalFrame = img.frameDic[img.sequenceDic[animPrefix + stateSuffix[(int)CONTROL_STATE.NORMAL]].frames[0]];
		else
			normalFrame = img.frameDic[img.sequenceDic[animPrefix].frames[0]];
		mTargetLayer.SetPosAndSize(x, y, width > 0 ? width : normalFrame.w, height > 0 ? height : normalFrame.h);
		
		RefreshControlState();
	}
	
	public void SetButtonOpt(bool isSys, UTVPImage img, string typeStr, string animPrefix, string isAnim,
		string leftStr, string topStr, string widthStr, string heightStr)
	{
		mIsSys = isSys;
		mIsAnim = mSystem.Str2Bool(isAnim);
		
		mTargetLayer.LoadImage(img);
		stateAnimNamePrefix = animPrefix;
		
		this.type = BUTTON_TYPE.NORMAL;
		if (typeStr != null)
			this.type = (BUTTON_TYPE)Enum.Parse(typeof(BUTTON_TYPE), typeStr.ToUpper());
		
		UTVPAnimFrameInfo normalFrame = null;
		if (mIsAnim)
			normalFrame = img.frameDic[img.sequenceDic[animPrefix + stateSuffix[(int)CONTROL_STATE.NORMAL]].frames[0]];
		else
			normalFrame = img.frameDic[img.sequenceDic[animPrefix].frames[0]];
		
		int left = mIsSys ? mTargetLayer.Left : (mParent.LocateX + mParent.MarginLeft);
		mSystem.Str2Number(leftStr, ref left);
		int top = mIsSys ? mTargetLayer.Top : (mParent.LocateY + mParent.MarginTop);
		mSystem.Str2Number(topStr, ref top);
		int width = normalFrame.w;
		mSystem.Str2Number(widthStr, ref width);
		int height = normalFrame.h;
		mSystem.Str2Number(heightStr, ref height);
		mTargetLayer.SetPosAndSize(left, top, width, height);
		
		RefreshControlState();
	}
	
	protected override void RefreshControlState()
	{
		if (_selected && (type == BUTTON_TYPE.RADIO || type == BUTTON_TYPE.CHECK))
		{
			if (mDisable)
				SetStateAnim(CONTROL_STATE.SELECTEDDISABLE);
			else if (mMouseDown)
				SetStateAnim(CONTROL_STATE.SELECTEDON);
			else if (mFocus)
				SetStateAnim(CONTROL_STATE.SELECTEDOVER);
			else
				SetStateAnim(CONTROL_STATE.SELECTEDNORMAL);
		}
		else
		{
			if (mDisable)
				SetStateAnim(CONTROL_STATE.DISABLE);
			else if (mMouseDown)
				SetStateAnim(CONTROL_STATE.ON);
			else if (mFocus)
				SetStateAnim(CONTROL_STATE.OVER);
			else
				SetStateAnim(CONTROL_STATE.NORMAL);
		}
	}
	
	readonly int[] defaultFrameList = {0, 0, 1, 0, 1, 4, 5, 4};
	private void SetStateAnim(CONTROL_STATE state)
	{
		if (mIsAnim)
		{
			mTargetLayer.StartAnimation(stateAnimNamePrefix + stateSuffix[(int)state], 0, false);
		}
		else
		{
			int frameIdx = (int)state;
			int frameNum = mTargetLayer.Image.sequenceDic[stateAnimNamePrefix].frames.Length;
			if (frameIdx >= frameNum)
			{
				while (frameIdx >= frameNum)
					frameIdx = defaultFrameList[frameIdx];
			}
			mTargetLayer.SetAnimOption(stateAnimNamePrefix, true, frameIdx, false);
		}
	}
	
	protected override void OnMouseDown_impl(UTVPLayer layer, int x, int y, KeyCode button, int shift)
	{
		base.OnMouseDown_impl(layer, x, y, button, shift);
		
		if (type == BUTTON_TYPE.AUTOREPEAT)
		{
			if (OnButtonClick != null)
				OnButtonClick(this);
			if (eventTarget != null)
				eventTarget.SendMessage("OnButtonClick", eventParam, SendMessageOptions.DontRequireReceiver);
		}
	}
	
	protected override void OnMouseUp_impl(UTVPLayer layer, int x, int y, KeyCode button, int shift)
	{
		bool isMouseDown = mouseDown;
		base.OnMouseUp_impl(layer, x, y, button, shift);
		if (isMouseDown)
		{
			if (type == BUTTON_TYPE.RADIO)
				selected = true;
			else if (type == BUTTON_TYPE.CHECK)
			selected = !selected;
		}
		
		if (OnButtonClick != null)
			OnButtonClick(this);
		if (eventTarget != null)
			eventTarget.SendMessage("OnButtonClick", eventParam, SendMessageOptions.DontRequireReceiver);	
		
		if (targetScenario != null)
			mSystem.conductor.LoadScenarioFile(targetScenario);
		if (targetLabel != null)
			mSystem.conductor.GoToLabel(targetLabel);
		if (targetScenario != null || targetLabel != null)
			mSystem.conductor.Run();
	}
	
	protected override void OnMouseEnter_impl(UTVPLayer layer)
	{
		base.OnMouseEnter_impl(layer);
		
		if (OnButtonEnter != null)
			OnButtonEnter(this);
		if (eventTarget != null)
			eventTarget.SendMessage("OnButtonMouseEnter", eventParam, SendMessageOptions.DontRequireReceiver);
	}
	
	protected override void OnMouseLeave_impl(UTVPLayer layer)
	{
		base.OnMouseLeave_impl(layer);
		
		if (OnButtonLeave != null)
			OnButtonLeave(this);
		if (eventTarget != null)
			eventTarget.SendMessage("OnButtonMouseLeave", eventParam, SendMessageOptions.DontRequireReceiver);
	}
	
	protected override UKagControlBase_SaveData CreateSaveDataBuff()
	{
		return new UKagButton_SaveData(); 
	}
	
	protected override void GetSelfData(UKagControlBase_SaveData dataBuff)
	{
		base.GetSelfData(dataBuff);
		
		UKagButton_SaveData dataBuffSelf = (UKagButton_SaveData)dataBuff;
		
		dataBuffSelf.type = type;
		dataBuffSelf.selected = _selected;
		
		dataBuffSelf.targetScenario = targetScenario;
		dataBuffSelf.targetLabel = targetLabel;
		
		dataBuffSelf.eventTarget = eventTarget.name;
		dataBuffSelf.eventParam = eventParam;
	}
	
	protected override void SetSelfData(UKagControlBase_SaveData dataBuff)
	{
		base.SetSelfData(dataBuff);
		
		UKagButton_SaveData dataBuffSelf = (UKagButton_SaveData)dataBuff;
		type = dataBuffSelf.type;
		_selected = dataBuffSelf.selected;
		
		targetScenario = dataBuffSelf.targetScenario;
		targetLabel = dataBuffSelf.targetLabel;
		
		eventTarget = GameObject.Find(dataBuffSelf.eventTarget);
		eventParam = dataBuffSelf.eventParam;
	}
}
